package com.lik888.web1.controller;


import com.lik888.web1.constants.Client;
import com.lik888.web1.entity.R;
import com.lik888.web1.entity.UserTable;
import com.lik888.web1.mapper.UserProductiontableMapper;
import com.lik888.web1.mapper.UserTableMapper;
import com.lik888.web1.mapper.UserproducionConnectiontableMapper;
import com.lik888.web1.service.IUserTableService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthGiteeRequest;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.redis.core.StringRedisTemplate;

import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/auth")
@RequiredArgsConstructor
public class RestAuthController {
    private final Client client;
    private final UserTableMapper userTableMapper;
   private final UserproducionConnectiontableMapper userproducionConnectiontableMapper;
   private final UserProductiontableMapper userProductiontableMapper;
   private final IUserTableService userTableService;
    private final PasswordEncoder passwordEncoder;
    @Autowired
    private  StringRedisTemplate redisTemplate;
    // 1. 发起授权：生成 state 并存到 Session
    @RequestMapping("/reader")
    public void readerAuth(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 生成随机 state
        String state = AuthStateUtils.createState();
        // 把 state 存到当前用户的 Session 中（key 用 "AUTH_STATE" 方便后续取出）
//        request.getSession().setAttribute("AUTH_STATE", state);
        redisTemplate.opsForValue().set("state:"+state, state,5, TimeUnit.SECONDS);
        // 发起授权，传入存好的 state
        AuthRequest authRequest = getAuthRequest();
        String authorizeUrl = authRequest.authorize(state);
        // 重定向到 Gitee 登录页
        response.sendRedirect(authorizeUrl);
    }

    @RequestMapping("/callback")
    @Transactional
    public Object callback(HttpServletRequest request, AuthCallback authCallback) throws Exception {
//        String savedState = (String) request.getSession().getAttribute("AUTH_STATE");
        String savedState = redisTemplate.opsForValue().get("state:"+authCallback.getState());
        // 从 Gitee 回调参数中取出返回的 state
        String callbackState = authCallback.getState();
        // 手动验证 state：如果不匹配，直接抛异常
        if (savedState == null || !savedState.equals(callbackState)) {
            throw new RuntimeException("Illegal state: 可能存在 CSRF 攻击风险");
        }
        // state 验证通过后，再执行登录逻辑
        AuthRequest authRequest = getAuthRequest();
        AuthResponse<AuthUser> login = authRequest.login(authCallback);
        String username = login.getData().getUsername();
        String uuid = login.getData().getUuid();
        //uuid转化为整形
        //此处uuid前缀+1 用于生成gitee用户的唯一标识
        String giteeUserId = "1" + uuid;
        //判断是不是第一次登陆
        UserTable userTableT = userTableMapper.selectById(Long.parseLong(uuid));
        if(userTableT != null){
            String login1 = userTableService.Login(userTableT.getUsername(), "123456");
            //如果密码正确 则直接登录
                return R.ok("不是第一次登陆，直接登录" + login1);
        }

        UserTable userTable = new UserTable();
        redisTemplate.delete("state:"+authCallback.getState());
        userTable.setUserApp(1);
        userTable.setAppId(Long.parseLong(giteeUserId));
        userTable.setUserId(Long.parseLong(uuid));
        userTable.setUsername(uuid);
        userTable.setPassword("123456");
        //调用login方法
        Boolean register = userTableService.Register(userTable);
        if(!register){
            throw new RuntimeException("注册失败");
        }
        String login1 = userTableService.Login(userTable.getUsername(), "123456");
        return R.ok("注册成功，直接登录" + login1);
    }

    // 初始化 AuthRequest（不变）
    private AuthRequest getAuthRequest() {
        return new AuthGiteeRequest(AuthConfig.builder()
                .clientId(client.getClientId())
                .clientSecret(client.getClientSecret())
                .redirectUri(client.getRedirectUri())
                .build());
    }

}